package nl.hanze.designpatterns.Models;

import nl.hanze.designpatterns.DAO.LoginCredentialDAO;
import nl.hanze.designpatterns.DAO.QuestionDAO;
import nl.hanze.designpatterns.DAO.TroubleTicketDAO;
import nl.hanze.designpatterns.DAOFactory.DAOFactory;
import nl.hanze.designpatterns.DAOFactory.impl.DAOFactoryAllFileImpl;
import nl.hanze.designpatterns.DAOFactory.impl.DAOFactoryLoginDBImpl;
import nl.hanze.designpatterns.DAOFactory.impl.DAOFactoryLoginFileImpl;
import nl.hanze.designpatterns.Domain.Answer;
import nl.hanze.designpatterns.Domain.LoginCredential;
import nl.hanze.designpatterns.Domain.Question;
import nl.hanze.designpatterns.Domain.TroubleTicket;
import nl.hanze.designpatterns.util;

import javax.swing.*;
import java.util.List;
import java.util.Observable;

/**
 *
 * Created by Aron on 23-9-2014.
 */
public class MainModel extends Observable {

    private LoginCredentialDAO loginCredentialDAO;
    private TroubleTicketDAO troubleTicketDAO;
    private QuestionDAO questionDAO;

    private DefaultListModel<TroubleTicket> ticketList = new DefaultListModel<>();
    public TroubleTicket selectedTicket = new TroubleTicket();

    private DefaultListModel<Question> questionList = new DefaultListModel<>();
    private DefaultListModel<Answer> answerList = new DefaultListModel<>();
    public Question selectedQuestion = new Question();
    public Answer selectedAnswer = new Answer();

    public String loggedInUser = "";

    public MainModel() {
        changeDAOFactory("DAOFactoryLoginDBImpl");
        selectQuestion(questionDAO.getRootQuestion());
    }

    public void changeDAOFactory(String DAOFactoryName){
        DAOFactory daoFactory;
        switch (DAOFactoryName){
            case "DAOFactoryLoginFileImpl":
                daoFactory = new DAOFactoryLoginFileImpl();
                break;
            case "DAOFactoryAllFileImpl":
                daoFactory = new DAOFactoryAllFileImpl();
                break;
            case "DAOFactoryLoginDBImpl":
            default:
                daoFactory = new DAOFactoryLoginDBImpl();
        }
        loginCredentialDAO = daoFactory.getLoginCredentialDAO();
        troubleTicketDAO = daoFactory.getTroubleTicketDAO();
        questionDAO = daoFactory.getQuestionDAO();
    }

    public String getLoggedInUser() {
        return loggedInUser;
    }

    private void setLoggedInUser(String loggedInUser) {
        this.loggedInUser = loggedInUser;
    }

    public boolean login(LoginCredential loginCredential){
        if (loginCredentialDAO.isValid(loginCredential)){
            setLoggedInUser(loginCredential.getUserName());
            newTicket();
            return true;
        } else {
            setLoggedInUser("");
            return false;
        }
    }

    public void logout(){
        setLoggedInUser("");
    }

    public void updateQuestionList() {
        List<Question> list = selectedQuestion.getQuestions();
        questionList.removeAllElements();
        for (Question question : list ) {
            questionList.addElement(question);
        }
    }

    public void updateAnswerList() {
        List<Answer> list = selectedQuestion.getAnswers();
        answerList.removeAllElements();
        for (Answer answer : list ) {
            answerList.addElement(answer);
        }
    }

    public void updateTicketList() {
        List<TroubleTicket> list = troubleTicketDAO.getTroubleTickets();
        ticketList.removeAllElements();
        for (TroubleTicket ticket : list ) {
            ticketList.addElement(ticket);
        }

    }

    public void selectTicket(TroubleTicket troubleTicket) {
        if (troubleTicket == null) {
            System.out.println("troubleTicket is null");
        } else if (selectedTicket != troubleTicket) {
            selectedTicket = troubleTicket;
            System.out.println("selected "+troubleTicket);
            setChanged();
            notifyObservers("ticket");
        } else {
            System.out.println("already selected "+troubleTicket);
        }
    }

    public void selectAnswer(Answer answer) {
        if (answer == null) {
            System.out.println("answer is null");
        } else if (selectedAnswer != answer) {
            selectedAnswer = answer;
            System.out.println("selectedAnswer "+answer);
            setChanged();
            notifyObservers("answer");
        } else {
            System.out.println("already selected "+answer);
        }
    }

    public void selectQuestion(Question question) {
        if (question == null) {
            System.out.println("question is null");
            Question rootQuestion = questionDAO.getRootQuestion();
            if (rootQuestion != null) {
                selectQuestion(questionDAO.getRootQuestion());
            } else {
                System.out.println("[No root question found!");
            }

        } else if (selectedQuestion != question) {
            selectedQuestion = question;
            updateQuestionList();
            updateAnswerList();
            System.out.println("selectedQuestion "+question);
            setChanged();
            notifyObservers("question");
            if (selectedQuestion.getAnswers().size() > 0){
                selectAnswer(selectedQuestion.getAnswers().get(0));
            } else {
                selectAnswer(new Answer());
            }
        } else {
            System.out.println("already selected "+question);
        }
    }

    public void newTicket(){
        TroubleTicket ticket = new TroubleTicket();
        ticket.setUserName(loggedInUser);
        ticket.setCallerName("");
        ticket.setDateTime(util.getCurrentDate());
        ticket.setDescription("");
        selectTicket(ticket);
    }

    public void saveTicket(){
        troubleTicketDAO.saveTroubleTicket(selectedTicket);
        updateTicketList();
    }

    public DefaultListModel<TroubleTicket> getTicketList() {
        updateTicketList();
        return ticketList;
    }

    public DefaultListModel<Answer> getAnswerList() {
        updateAnswerList();
        return answerList;
    }

    public DefaultListModel<Question> getQuestionList() {
        updateQuestionList();
        return questionList;
    }

}
